package cn.yto.print.system;

import cn.yto.print.config.ThreadPoolManager;
import cn.yto.print.config.i18n.I18nResourceManager;
import cn.yto.print.constants.AssistantConstants;
import com.jfoenix.controls.JFXProgressBar;
import de.felixroske.jfxsupport.SplashScreen;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Label;

import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class MySplashScreen extends SplashScreen {

    private static final int TOTAL_STEPS = 50;
    private static final long STEP_DELAY_MS = 50L;

    private final I18nResourceManager i18n = I18nResourceManager.getInstance();

    private Label label;
    private JFXProgressBar progressBar;

    public MySplashScreen() {
        super();
    }

    @Override
    public Parent getParent() {
        FXMLLoader loader = new FXMLLoader(
                getClass().getResource("/fxml/loader.fxml"),
                i18n.getResourceBundle()
        );

        Node rootNode = loadFXML(loader);
        bindUIControls(rootNode);
        setAppTitleLabel(rootNode);
        startProgressSimulation();
        return (Parent) rootNode;
    }

    private Node loadFXML(FXMLLoader loader) {
        try {
            return loader.load();
        } catch (IOException e) {
            throw new RuntimeException("加载 FXML 失败", e);
        }
    }

    private void bindUIControls(Node rootNode) {
        this.label = Optional.ofNullable((Label) rootNode.lookup("#progressLabel")).orElseThrow(IllegalStateException::new);
        this.progressBar = Optional.ofNullable((JFXProgressBar) rootNode.lookup("#progressBar")).orElseThrow(IllegalStateException::new);
    }

    private void setAppTitleLabel(Node rootNode) {
        Optional.ofNullable((Label) rootNode.lookup("#textLabel"))
                .ifPresent(label -> {
                    String title = String.join("_v",
                            i18n.get("app.show.title"), System.getProperty(AssistantConstants.APP_VERSION)) + " Build 2025";
                    label.setText(title);
                });
    }

    private void startProgressSimulation() {
        CompletableFuture.runAsync(() -> {
            IntStream.rangeClosed(1, TOTAL_STEPS)
                    .forEach(step -> {
                        double progress = step / (double) TOTAL_STEPS;
                        Platform.runLater(() -> progressBar.setProgress(progress));
                        sleepStepDelay();
                    });
            Platform.runLater(this::loadCompleted);
        }, ThreadPoolManager.getExecutorService());
    }

    private void sleepStepDelay() {
        try {
            TimeUnit.MILLISECONDS.sleep(STEP_DELAY_MS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("进度条加载被中断", e);
        }
    }

    private void loadCompleted() {
        progressBar.setProgress(1.0);
        label.setText(i18n.get("splash.screen.loading"));
    }

}
